package cn.iocoder.yudao.module.worker.service.trend;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.extra.spring.SpringUtil;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
import cn.iocoder.yudao.module.member.api.point.MemberPointApi;
import cn.iocoder.yudao.module.member.api.user.MemberUserApi;
import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO;
import cn.iocoder.yudao.module.member.enums.point.MemberPointBizTypeEnum;
import cn.iocoder.yudao.module.system.api.social.SocialClientApi;
import cn.iocoder.yudao.module.system.api.social.dto.SocialWxaSubscribeMessageSendReqDTO;
import cn.iocoder.yudao.module.trade.api.config.TradeConfigApi;
import cn.iocoder.yudao.module.trade.api.config.dto.TradeConfigRespDTO;
import cn.iocoder.yudao.module.worker.controller.app.trend.vo.AppWorkerTrendPageReqVO;
import cn.iocoder.yudao.module.worker.controller.app.trend.vo.AppWorkerTrendSaveReqVO;
import cn.iocoder.yudao.module.worker.dal.dataobject.clerk.ClerkDO;
import cn.iocoder.yudao.module.worker.dal.mysql.clerk.ClerkMapper;
import cn.iocoder.yudao.module.worker.enums.trend.TrendFileTypeEnum;
import cn.iocoder.yudao.module.worker.enums.trend.TrendTypeEnum;
import org.apache.commons.lang3.StringUtils;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import cn.iocoder.yudao.module.worker.controller.admin.trend.vo.*;
import cn.iocoder.yudao.module.worker.dal.dataobject.trend.WorkerTrendDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;

import cn.iocoder.yudao.module.worker.dal.mysql.trend.WorkerTrendMapper;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.member.enums.ErrorCodeConstants.*;
import static cn.iocoder.yudao.module.worker.enums.ErrorCodeConstants.*;
import static cn.iocoder.yudao.module.worker.enums.MessageTemplateConstants.TREND_APPLY_SUCCESS;

/**
 * 店员动态 Service 实现类
 *
 * @author Jerry
 */
@Service
@Validated
public class WorkerTrendServiceImpl implements WorkerTrendService {

    @Resource
    private WorkerTrendMapper trendMapper;

    @Resource
    private ClerkMapper clerkMapper;

    @Resource
    private MemberUserApi memberUserApi;

    @Resource
    private MemberPointApi memberPointApi;

    @Resource
    private TradeConfigApi tradeConfigApi;

    @Resource
    public SocialClientApi socialClientApi;

    @Override
    public Long createTrend(WorkerTrendSaveReqVO createReqVO) {
        // 插入
        WorkerTrendDO trend = BeanUtils.toBean(createReqVO, WorkerTrendDO.class);
        trendMapper.insert(trend);
        // 返回
        return trend.getId();
    }

    @Override
    public void updateTrend(WorkerTrendSaveReqVO updateReqVO) {
        // 校验存在
        validateTrendExists(updateReqVO.getId());
        // 更新
        WorkerTrendDO updateObj = BeanUtils.toBean(updateReqVO, WorkerTrendDO.class);
        trendMapper.updateById(updateObj);
    }

    @Override
    public void deleteTrend(Long id) {
        // 校验存在
        validateTrendExists(id);
        // 删除
        trendMapper.deleteById(id);
    }

    private void validateTrendExists(Long id) {
        if (trendMapper.selectById(id) == null) {
            throw exception(TREND_NOT_EXISTS);
        }
    }

    @Override
    public WorkerTrendDO getTrend(Long id) {
        return trendMapper.selectById(id);
    }

    @Override
    public PageResult<WorkerTrendDO> getTrendPage(WorkerTrendPageReqVO pageReqVO) {
        return trendMapper.selectPage(pageReqVO);
    }

    @Override
    public Long createTrend(AppWorkerTrendSaveReqVO createReqVO) {
        MemberUserRespDTO member = memberUserApi.getUser(createReqVO.getUserId());
        if(CommonStatusEnum.isDisable(member.getStatus())){
            throw exception(AUTH_LOGIN_USER_DISABLED);
        }

        TradeConfigRespDTO config = tradeConfigApi.getTradeConfig();
        if(createReqVO.getWorkerClerkId() == null || createReqVO.getWorkerClerkId() < 0){
            if(!config.getFriendEnabled()){
                throw exception(TREND_WORKER);
            }
        }

        if(!config.getAuthEnabled() && config.getFriendEnabled()){
            if(StringUtils.isBlank(member.getPhoto())){
                throw exception(USER_PHOTO_EMPTY);
            }
        }

        boolean flag = checkAd(createReqVO);

        if(member.getPoint() < config.getTrendPoint() && flag){
            if(member.getVipEndTime() == null){
                throw exception(TREND_VIP_NOT_EXISTS);
            }else{
                if(member.getVipEndTime().isBefore(DateUtil.toLocalDateTime(DateUtil.date()))){
                    throw exception(TREND_VIP_NOT_EXISTS);
                }else{
                    // 会员发布动态免费
                    DateTime lastSecondOfDay = DateUtil.endOfDay(DateUtil.date());
                    if(member.getPostTime() == null){
                        member.setPostTime(DateUtil.toLocalDateTime(lastSecondOfDay));
                        member.setPostNum(3);
                        member.setSlashedNum(3);
                        member.setWechatNum(5);

                        flag = false;
                        config.setTrendPoint(0);
                        Integer postNum = member.getPostNum()-1;
                        member.setPostNum(postNum);
                    }else{
                        if(DateUtil.toLocalDateTime(DateUtil.date()).isAfter(member.getPostTime())){
                            member.setPostTime(DateUtil.toLocalDateTime(lastSecondOfDay));
                            member.setPostNum(3);
                            member.setSlashedNum(3);
                            member.setWechatNum(5);
                        }

                        if(member.getPostNum() > 0){
                            flag = false;
                            config.setTrendPoint(0);
                            Integer postNum = member.getPostNum()-1;
                            if(postNum < 0){
                                postNum = 0;
                            }
                            member.setPostNum(postNum);
                        }else{
                            throw exception(TREND_POINT_NOT_EXISTS, config.getTrendPoint());
                        }
                    }
                }
            }
        }

        WorkerTrendDO trend = BeanUtils.toBean(createReqVO, WorkerTrendDO.class);
        if(trend.getWorkerClerkId() == null || trend.getWorkerClerkId() < 0){
            trend.setWorkerClerkId(null);
            trend.setTrendType(TrendTypeEnum.MEMBER.getType());
        }else{
            trend.setTrendType(TrendTypeEnum.CLERK.getType());
            ClerkDO clerkDO = clerkMapper.getClerk(trend.getUserId(), trend.getWorkerClerkId());
            if(clerkDO == null){
                throw exception(TREND_CLERK_NOT_EXISTS);
            }
        }

        // 自动审核
        trend.setStatus(checkMessage(createReqVO));
        trend.setAdStatus(flag);

        // 插入
        trendMapper.insert(trend);

        // 更新会员次数
        memberUserApi.updateUserVip(member);

        // 消耗积分
        if(config.getTrendPoint() > 0 && flag){
            memberPointApi.reducePoint(createReqVO.getUserId(), config.getTrendPoint(), MemberPointBizTypeEnum.TREND.getType(), String.valueOf(trend.getId()));
        }

        // 发送通知
        getSelf().sendApplyResultMessage(member, trend);

        // 返回
        return trend.getId();
    }

    @Async
    public void sendApplyResultMessage(MemberUserRespDTO member, WorkerTrendDO trend) {
        if(trend.getStatus().equals(true)){
            socialClientApi.sendWxaSubscribeMessage(new SocialWxaSubscribeMessageSendReqDTO()
                    .setUserId(trend.getUserId()).setUserType(UserTypeEnum.MEMBER.getValue())
                    .setTemplateTitle(TREND_APPLY_SUCCESS)
                    .setPage("pages/tabbar/index") // 首页
                    .addMessage("name3", member.getNickname()) // 会员昵称
                    .addMessage("thing1", "您的帖子已审核通过") // 审核结果
                    .addMessage("date4", DateUtil.now())); // 通过时间
        }
    }

    /**
     * 内容审核
     * @param createReqVO
     */
    private boolean checkMessage(AppWorkerTrendSaveReqVO createReqVO) {
        boolean check = false;

        if(TrendFileTypeEnum.IMAGE.getType().equals(createReqVO.getFileType())){
            if(StringUtils.isNotBlank(createReqVO.getFile())){
                String[] imgList = createReqVO.getFile().split(",");
                for(String img : imgList){
                    String url = socialClientApi.getQrCode(img);
                    if(StringUtils.isNotBlank(url)){
                        if(!url.contains("https://u.wechat.com")){
                            return false;
                        }
                    }
                }
            }
        }

        try {
            check = tradeConfigApi.checkMessage(createReqVO.getContent(), String.valueOf(createReqVO.getUserId()));
        }catch (Exception e){
            throw exception(TREND_ERROR);
        }

        if(check){
            if(TrendFileTypeEnum.IMAGE.getType().equals(createReqVO.getFileType())){
                try {
                    String[] imgList = createReqVO.getFile().split(",");
                    for(String img : imgList){
                        check = tradeConfigApi.checkImg(img, String.valueOf(createReqVO.getUserId()));
                        if(!check){
                            return false;
                        }
                    }
                }catch (Exception e){
                    throw exception(TREND_ERROR);
                }
            }else if(TrendFileTypeEnum.VOICE.getType().equals(createReqVO.getFileType())){
                try {
                    check = tradeConfigApi.checkVoice(createReqVO.getFile(), String.valueOf(createReqVO.getUserId()));
                }catch (Exception e){
                    throw exception(TREND_ERROR);
                }
            }else{
                check = false;
            }
        }
        return check;
    }

    /**
     * 检测是否含二维码
     * @param createReqVO
     */
    private boolean checkAd(AppWorkerTrendSaveReqVO createReqVO) {
        boolean check = false;
        if(TrendFileTypeEnum.IMAGE.getType().equals(createReqVO.getFileType())){
            if(StringUtils.isNotBlank(createReqVO.getFile())){
                String[] imgList = createReqVO.getFile().split(",");
                for(String img : imgList){
                    String url = socialClientApi.getQrCode(img);
                    if(StringUtils.isNotBlank(url)){
                        return true;
                    }
                }
            }
        }
        return check;
    }

    @Override
    public void updateTrend(AppWorkerTrendSaveReqVO updateReqVO) {
        // 校验存在
        validateTrendExists(updateReqVO.getId());
        // 更新
        WorkerTrendDO updateObj = BeanUtils.toBean(updateReqVO, WorkerTrendDO.class);
        trendMapper.updateById(updateObj);
    }

    @Override
    public PageResult<WorkerTrendDO> getTrendPage(AppWorkerTrendPageReqVO pageReqVO) {
        TradeConfigRespDTO config = tradeConfigApi.getTradeConfig();
        if(!config.getFriendEnabled()){
            pageReqVO.setTrendType(TrendTypeEnum.CLERK.getType());
        }
        return trendMapper.selectPage(pageReqVO);
    }

    @Override
    public Integer getTrendNum(Long workerClerkId) {
        return trendMapper.getTrendNum(workerClerkId);
    }

    @Override
    public PageResult<WorkerTrendDO> getMyTrendPage(AppWorkerTrendPageReqVO pageReqVO) {
        return trendMapper.getMyTrendPage(pageReqVO);
    }

    /**
     * 获得自身的代理对象，解决 AOP 生效问题
     *
     * @return 自己
     */
    private WorkerTrendServiceImpl getSelf() {
        return SpringUtil.getBean(getClass());
    }

}